home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / C / Applications / µSim 1.0.5 / source / Assembler.c < prev    next >
Encoding:
Text File  |  1995-11-01  |  12.4 KB  |  466 lines  |  [TEXT/CWIE]

  1. /*
  2. Copyright © 1993,1994,1995 Fabrizio Oddone
  3. ••• ••• ••• ••• ••• ••• ••• ••• ••• •••
  4. This source code is distributed as freeware:
  5. you may copy, exchange, modify this code.
  6. You may include this code in any kind of application: freeware,
  7. shareware, or commercial, provided that full credits are given.
  8. You may not sell or distribute this code for profit.
  9. */
  10.  
  11. //#pragma load "MacDump"
  12.  
  13. #pragma fourbyteints on
  14. #include    <ctype.h>
  15. #include    <stdlib.h>
  16. #pragma fourbyteints reset
  17.  
  18. #include    "UtilsSys7.h"
  19. #include    "Conversions.h"
  20. #include    "MovableModal.h"
  21.  
  22. #include    "Assembler.h"
  23. #include    "Compares.h"
  24. #include    "Disasm.h"
  25. #include    "DoEditDialog.h"
  26. #include    "DoMenu.h"
  27. #include    "Dump.h"
  28. #include    "Globals.h"
  29. #include    "Main.h"
  30. #include    "Microprogram_Ed.h"
  31. #include    "SimUtils.h"
  32.  
  33. #if defined(FabSystem7orlater)
  34.  
  35. #pragma fourbyteints on
  36. #pragma segment Rare
  37.  
  38. enum {
  39. kOPCMAXLEN = 4,
  40. kGROW_SYMTAB = 50,
  41. kGROW_OBJTAB = 150,
  42. kBITS_12 = 0x0FFF,
  43. kBITS_11 = 0x07FF,
  44. kBITS_8 = 0x00FF
  45. };
  46.  
  47. struct symtable {
  48.     StringHandle    symb;
  49.     long    value;
  50.     };
  51.  
  52. typedef struct symtable symtable;
  53. typedef symtable *symtablePtr;
  54. typedef symtablePtr *symtableHandle;
  55.  
  56. #if defined(powerc) || defined (__powerc)
  57. #pragma options align=mac68k
  58. #endif
  59. struct objtable {
  60.     long    operand;
  61.     Byte    length;
  62.     Byte    classe;
  63.     unsigned short    opcod;
  64.     Boolean    isSymbol;
  65.     Boolean    reserved;
  66.     };
  67. #if defined(powerc) || defined(__powerc)
  68. #pragma options align=reset
  69. #endif
  70.  
  71. typedef struct objtable objtable;
  72. typedef objtable *objtablePtr;
  73. typedef objtablePtr *objtableHandle;
  74.  
  75. static OSErr OnePassAsm(Handle fileBuffer);
  76. static long CountReturns(Handle fileBuffer, char *lastpos);
  77. static Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr theD);
  78. //static pascal Boolean AsmEditNumFilter(DialogPtr, EventRecord *, short *);
  79.  
  80.  
  81. /* myAsmFile: reads theFile to be assembled into memory */
  82.  
  83. OSErr myAsmFile(FSSpec *theFile)
  84. {
  85. ParamBlockRec    myPB;
  86. EventRecord    dummyEv;
  87. register Handle    tempBuffer;
  88. unsigned long    fileSize;
  89. short    asmFileRefN;
  90. register OSErr    err;
  91.  
  92. SetCursor(*gWatchHandle);
  93. if ((err = FSpOpenDFCompat(theFile, fsRdPerm, &asmFileRefN)) == noErr) {
  94.     if ((err = GetEOF(asmFileRefN, (long *)&fileSize)) == noErr) {
  95.         if (tempBuffer = NewHandleGeneral(fileSize)) {
  96.             myPB.ioParam.ioCompletion = nil;
  97.             myPB.ioParam.ioRefNum = asmFileRefN;
  98.             HLock(tempBuffer);
  99.             myPB.ioParam.ioBuffer = *tempBuffer;
  100.             myPB.ioParam.ioReqCount = fileSize;
  101.             myPB.ioParam.ioPosMode = fsFromStart | kNoCacheMask;
  102.             myPB.ioParam.ioPosOffset = 0L;
  103.             (void)PBReadAsync(&myPB);
  104.             while (myPB.ioParam.ioResult > 0) {
  105.                 SystemTask();
  106.                 (void)EventAvail(everyEvent, &dummyEv);
  107.                 }
  108.             HUnlock(tempBuffer);
  109.             if ((err = myPB.ioParam.ioResult) == noErr) {
  110.                 /* Do damned assembling */
  111.                 err = OnePassAsm(tempBuffer);
  112.                 InvalDump();
  113.                 InvalDisasm();
  114.                 }
  115.             DisposeHandle(tempBuffer);
  116.             }
  117.         else err = MemError();
  118.         }
  119.     (void)FSClose(asmFileRefN);
  120.     }
  121. InitCursor();
  122. return(err);
  123. }
  124.  
  125. /* OnePassAsm: assembles the file passed in the buffer */
  126.  
  127. static OSErr OnePassAsm(Handle fileBuffer)
  128. {
  129. Str255    tempS;
  130. Handle    SortedOpcodeTable;
  131. symtableHandle    SymbolTable;
  132. objtableHandle    ObjTable;
  133. Handle    tempH;
  134. Ptr    myEOF;
  135. long    ILC;
  136. ROpcodePtr    found;
  137. symtablePtr    foundsym;
  138. Size    ObjTabOffset, SymTabOffset, tmpSize;
  139. int    numinstr;
  140. short    build;
  141. OSErr    err;
  142. register Byte    i;
  143. register char *ex = nil;
  144. register char *copy;
  145.  
  146. err = noErr;
  147. ILC = (long)gILCBase << 1;
  148. DetachResource(SortedOpcodeTable = Get1Resource(krInstructions, kOPCODES));
  149. HNoPurge(SortedOpcodeTable);
  150. qsort((*SortedOpcodeTable) + 2, numinstr = (*(unsigned short *)*SortedOpcodeTable) + 1,
  151.     sizeof(ROpcode), compareMnem);
  152.  
  153. /* init symbol & object table */
  154. if ((SymbolTable = (symtableHandle)NewHandleGeneral(sizeof(symtable)*kGROW_SYMTAB))) {
  155.     if ((ObjTable = (objtableHandle)NewHandleGeneral(sizeof(objtable)*kGROW_OBJTAB))) {
  156.         SymTabOffset = 0L;
  157.         ObjTabOffset = 0L;
  158.         HLock(fileBuffer);
  159.         ex = *fileBuffer;
  160.         myEOF = (Ptr)((Size)ex + InlineGetHandleSize(fileBuffer));
  161.         do {
  162.             if (*ex == 13)
  163.                 ex++;
  164.             else {
  165.                 if (ispunct(*ex))
  166.                     while (*ex++ != 13)
  167.                         ;
  168.                 else {
  169.                     if (isspace(*ex) == 0) {
  170.                         copy = (char *)&tempS[1];
  171.                         i = 0;
  172.                         do {
  173.                             *copy++ = *ex++;
  174.                             i++;
  175.                             }
  176.                         while (isspace(*ex) == 0);
  177.                         tempS[0] = i;
  178.                         /* add to symbol table */
  179.                         if (SymTabOffset >= (tmpSize = InlineGetHandleSize((Handle)SymbolTable)))
  180.                             SetHandleSize((Handle)SymbolTable, tmpSize + sizeof(symtable)*kGROW_SYMTAB);
  181.                         tempH = (Handle)NewString(tempS);
  182.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->symb = (StringHandle)tempH;
  183.                         ((symtablePtr)(*(Handle)SymbolTable + SymTabOffset))->value = ILC;
  184.                         SymTabOffset += sizeof(symtable);
  185.                         }
  186.                     if (*ex == 13)
  187.                         ex++;
  188.                     else {
  189.                         while (isspace(*ex++))
  190.                             ;
  191.                         --ex;
  192.                         copy = (char *)&tempS;
  193.                         i = 0;
  194.                         do {
  195.                             *copy++ = *ex++;
  196.                             i++;
  197.                             }
  198.                         while (isspace(*ex) == 0);
  199.                         if (i > kOPCMAXLEN) {
  200.                             err = kasmErrInvalidOpcode;
  201.                             break;
  202.                             }
  203.                         else {
  204.                             while (i < kOPCMAXLEN) {
  205.                                 i++;
  206.                                 *copy++ = ' ';
  207.                                 }
  208.                             if (ObjTabOffset >= (tmpSize = InlineGetHandleSize((Handle)ObjTable)))
  209.                                 SetHandleSize((Handle)ObjTable, tmpSize + sizeof(objtable)*kGROW_OBJTAB);
  210.                             found = (ROpcodePtr)bsearch(&tempS, (*SortedOpcodeTable)+2,
  211.                                     numinstr, sizeof(ROpcode), compareMnem);
  212.                             if (found == nil) {
  213.                                 err = kasmErrInvalidOpcode;
  214.                                 break;
  215.                                 }
  216.                             else {
  217.                                 *(long *)&((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->length = *(long *)(&found->length);
  218.                                 i = found->classe;
  219.                                 if (i == kCLASS_16_0) {
  220.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  221.                                     ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = 0L;
  222.                                     }
  223.                                 else {
  224.                                     while (isspace(*ex++))
  225.                                         ;
  226.                                     --ex;
  227.                                     if (*ex == '#') {
  228.                                         ++ex;
  229.                                         copy = (char *)&tempS[1];
  230.                                         i = 0;
  231.                                         do {
  232.                                             *copy++ = *ex++;
  233.                                             i++;
  234.                                             }
  235.                                         while (isspace(*ex) == 0);
  236.                                         tempS[0] = i;
  237.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = false;
  238.                                         StringToNum(tempS, &((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand);
  239.                                         }
  240.                                     else {
  241.                                         copy = (char *)&tempS[1];
  242.                                         i = 0;
  243.                                         do {
  244.                                             *copy++ = *ex++;
  245.                                             i++;
  246.                                             }
  247.                                         while (isspace(*ex) == 0);
  248.                                         tempS[0] = i;
  249.                                         tempH = (Handle)NewString(tempS);
  250.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->isSymbol = true;
  251.                                         ((objtablePtr)(*(Handle)ObjTable + ObjTabOffset))->operand = (long)tempH;
  252.                                         }
  253.                                     }
  254.                                 ObjTabOffset += sizeof(objtable);
  255.                                 }
  256.                             while (*ex++ != 13)
  257.                                 ;
  258.                             ILC += found->length;
  259.                             }
  260.                         }
  261.                     }
  262.                 }
  263.             }
  264.         while (ex < myEOF);
  265.         HUnlock(fileBuffer);
  266.         if (err == noErr)
  267.             /* check for ILC out of bounds */
  268.             if (ILC > kSIZE_RAM - 4096)
  269.                 err = kasmErrPotHeapDamage;
  270.         if (err == noErr) {
  271.             ILC = (long)gILCBase << 1;
  272.             qsort(*SymbolTable, SymTabOffset / sizeof(symtable), sizeof(symtable), cmpsymb);
  273.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable)) {
  274.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol) {
  275.                     foundsym = (symtablePtr)
  276.                         bsearch(&((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand,
  277.                         *SymbolTable, SymTabOffset / sizeof(symtable),
  278.                         sizeof(symtable), cmpsymb);
  279.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol = false;
  280.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  281.                     ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand =
  282.                             (foundsym ? (((objtablePtr)(*(Handle)ObjTable + tmpSize))->classe >= kCLASS_16_16_REL
  283.                             ? (foundsym->value - ILC - ((objtablePtr)(*(Handle)ObjTable + tmpSize))->length) >> 1
  284.                             : foundsym->value) : (err = kasmErrSymbolNotDef, 0L));
  285.                     }
  286.                 switch (((objtablePtr)(*(Handle)ObjTable + tmpSize))->classe) {
  287.                     case kCLASS_4_12:
  288.                     case kCLASS_4_12_REL:
  289.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  290.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_12));
  291.                         *(short *)(gMMemory + ILC) = build;
  292.                         ILC += 2;
  293.                         break;
  294.                     case kCLASS_5_11:
  295.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  296.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_11));
  297.                         *(short *)(gMMemory + ILC) = build;
  298.                         ILC += 2;
  299.                         break;
  300.                     case kCLASS_8_8:
  301.                         build = (((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod |
  302.                             (((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand & kBITS_8));
  303.                         *(short *)(gMMemory + ILC) = build;
  304.                         ILC += 2;
  305.                         break;
  306.                     case kCLASS_16_0:
  307.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  308.                         ILC += 2;
  309.                         break;
  310.                     case kCLASS_16_16:
  311.                     case kCLASS_16_16_REL:
  312.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->opcod;
  313.                         ILC += 2;
  314.                         *(short *)(gMMemory + ILC) = ((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand;
  315.                         ILC += 2;
  316.                         break;
  317.                     }
  318.                 }
  319.             }
  320.         if ((err != noErr) && (err != kasmErrSymbolNotDef))
  321.             for(tmpSize = 0; tmpSize < ObjTabOffset; tmpSize += sizeof(objtable))
  322.                 if (((objtablePtr)(*(Handle)ObjTable + tmpSize))->isSymbol)
  323.                     DisposeHandle((Handle)((objtablePtr)(*(Handle)ObjTable + tmpSize))->operand);
  324.         for(tmpSize = 0; tmpSize < SymTabOffset; tmpSize += sizeof(symtable))
  325.             DisposeHandle((Handle)((symtablePtr)(*(Handle)SymbolTable + tmpSize))->symb);
  326.         DisposeHandle((Handle)ObjTable);
  327.         }
  328.     else err = MemError();
  329.     DisposeHandle((Handle)SymbolTable);
  330.     }
  331. else err = MemError();
  332. DisposeHandle(SortedOpcodeTable);
  333. if (err > 0) {
  334.     InitCursor();
  335.     if (ex)
  336.         MyNumToString(1L + CountReturns(fileBuffer, ex), tempS);
  337.     else
  338.         *(short *)tempS = 0x013F;
  339.     ParamText(tempS, nil, nil, nil);
  340.     StopAlert_UPP(kALRT_ASM + err, myStdFilterProcNoCancel);
  341.     err = 0;
  342.     }
  343. return err;
  344. }
  345.  
  346. static long CountReturns(Handle fileBuffer, char *lastpos)
  347. {
  348. register char *scanptr;
  349. register char *end = StripAddress(lastpos);
  350. register long    cnt = 0L;
  351.  
  352. for ( scanptr = StripAddress(*fileBuffer); scanptr <= end; )
  353.     if (*scanptr++ == 13)
  354.         ++cnt;
  355. return cnt;
  356. }
  357.  
  358.  
  359. enum {
  360. kDLOG_ASMPREFS = 263,
  361. kItemAsmDestLoc = 3
  362. };
  363.  
  364. void DoAsmPrefsDialog(void)
  365. {
  366. Str255    AsmDestStr;
  367.  
  368. dialogItems    things[] = {{ ok, 0, 1L },
  369.                         { cancel, 0, 0L },
  370.                         { kItemAsmDestLoc, 0, 0L },
  371.                         { 0, 0, 0L}
  372.                         };
  373.  
  374. things[kItemAsmDestLoc-1].refCon = (long)&AsmDestStr;
  375.  
  376. ShortToHexString(gILCBase, AsmDestStr);
  377.  
  378. if (HandleMovableModalDialog(things, gPrefs.remembWind ? &gPrefs.asmPrefsTL : nil, nil, nil, nil, nil, nil,
  379.     AdjustMenus,
  380.     Handle_My_Menu,
  381.     DomyKeyEvent,
  382.     AsmPrefsPreProcessKey,
  383.     nil,
  384.     DoUpdate,
  385.     DoActivate,
  386.     DoHighLevelEvent,
  387.     DoOSEvent,
  388.     DoIdle,
  389.     ULONG_MAX,
  390.     kDLOG_ASMPREFS) == ok) {
  391.     HexStringToShort(AsmDestStr, (short *)&gILCBase);
  392.     }
  393. }
  394.  
  395. Boolean AsmPrefsPreProcessKey(EventRecord *thEv, DialogPtr /*theD*/)
  396. {
  397. //short    iHit;
  398. unsigned char    keypressed;
  399. Boolean    result = true;
  400.  
  401. keypressed = CHARFROMMESSAGE(thEv->message);
  402. if ((keypressed >= 'a') && (keypressed <= 'z')) {
  403.     keypressed -= 'a' - 'A';    /* cambiare! */
  404.     CHARFROMMESSAGE(thEv->message) = keypressed;
  405.     }
  406. //iHit = ((DialogPeek)theD)->editField + 1;
  407. if (keypressed >= 32 && ((thEv->modifiers & cmdKey) == 0)) {
  408.     result = ( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed,
  409.                             1L, 0L, 0L) >= 0L );
  410.     }
  411. return result;
  412. }
  413.  
  414. /* AsmEditNumFilter: filterProc for the asm prefs dialog */
  415. /*
  416. static pascal Boolean AsmEditNumFilter(DialogPtr theD, EventRecord *thEv, short *iHit)
  417. {
  418. enum {
  419. kITEM_VALUE = 3
  420. };
  421.  
  422. GrafPtr    savePort;
  423. unsigned char    keypressed;
  424. register Boolean    retVal;
  425.  
  426. switch(thEv->what) {
  427.     case keyDown    :
  428.     case autoKey    :
  429.         keypressed = CHARFROMMESSAGE(thEv->message);
  430.         if ((keypressed >= 'a') && (keypressed <= 'z')) {
  431.             keypressed -= 'a' - 'A';
  432.             CHARFROMMESSAGE(thEv->message) = keypressed;
  433.             }
  434.         if ((keypressed >= 32) && (keypressed != 0x7F) && ((thEv->modifiers & cmdKey) == 0)) {
  435.             *iHit = kITEM_VALUE;
  436.             return( Munger((Handle)GetString(kSTR_HEXALLOWED), 1L, &keypressed, 1L, 0L, 0L) < 0L );
  437.             }
  438.         break;
  439.     case updateEvt:
  440.         if (theD != (DialogPtr)thEv->message) {
  441.             DoUpdate(thEv);
  442.             *iHit = kfakeUpdateItem;
  443.             return true;
  444.             }
  445.         break;
  446.     case activateEvt:
  447.         if (theD != (DialogPtr)thEv->message) {
  448.             DoActivate(thEv);
  449.             *iHit = kfakeUpdateItem;
  450.             return true;
  451.             }
  452.         break;
  453.     }
  454. GetPort(&savePort);
  455. SetPort(theD);
  456. retVal = StdFilterProc(theD, thEv, iHit);
  457. SetPort(savePort);
  458. return retVal;
  459. }
  460. */
  461.  
  462. #pragma fourbyteints reset
  463.  
  464. #endif
  465.  
  466.